package cn.huiyunche.base.service.interfaces.impl;


import cn.huiyunche.base.service.enums.ImportResultCodeEnum;
import cn.huiyunche.base.service.enums.LaborImportResultEnum;
import cn.huiyunche.base.service.form.ScPriceconfFreightVlidateLogForm;
import cn.huiyunche.base.service.interfaces.LaborPriceImportService;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.query.ScPriceconfFreightValidateQueryConditions;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.base.service.vo.ScPriceconfFreightValidateLogVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Administrator on 2017/5/8.
 */
@Service
public class LaborPriceImportServiceImpl implements LaborPriceImportService {

    private static final Logger logger = LoggerFactory.getLogger(LaborPriceImportServiceImpl.class);

    @Autowired
    private ScPriceconfFreightValidateLogMapper scPriceconfFreightValidateLogMapper;

    @Autowired
    private DRouteMapper dRouteMapper;

    @Autowired
    private ScPriceconfMileMapper scPriceconfMileMapper;

    @Autowired
    private ScPriceconfFreightMapper scPriceconfFreightMapper;

    @Autowired
    private ScPriceconfFreightImportLogMapper scPriceconfFreightImportLogmapper;

    @Override
    public void importExcel(List<ScPriceconfFreightValidateLogVo> list, String batchId) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        logger.info("import start: LaborPriceImportServiceImpl job time: {}", new Date().toString());
        try {
            for (ScPriceconfFreightValidateLogVo vo : list) {
                vo.setEffectiveDate(StringUtils.isEmpty(vo.getEffectiveDateString()) ? null : sdf.parse(vo.getEffectiveDateString()));
                vo.setBatchId(batchId);
            }
            scPriceconfFreightValidateLogMapper.insertList(list);
        } catch (Exception e) {
            logger.error("import fail: LaborPriceImportServiceImpl job time: {}" + e.getMessage());
            throw new BusinessException("导入失败");
        }
    }

    @Override
    public Map<String, Object> selectListByConditions(PageVo pageVo, ScPriceconfFreightValidateQueryConditions conditions) throws Exception {
        logger.info("LaborPriceImportServiceImpl.selectListByConditions params : {}, {}", pageVo, conditions);
        Map<String, Object> map = new HashMap<>();
//        ScPriceconfFreightValidateLogVo vo = new ScPriceconfFreightValidateLogVo();
//        vo.setBatchId(conditions.getBatchId());
//        vo.setLimitStart(pageVo.getStartIndex());
//        vo.setLimitEnd(pageVo.getPageSize());
        ScPriceconfFreightValidateLogExample example = new ScPriceconfFreightValidateLogExample();
        example.createCriteria().andBatchIdEqualTo(conditions.getBatchId());
        example.setLimitStart(pageVo.getStartIndex());
        example.setLimitEnd(pageVo.getPageSize());
        List<ScPriceconfFreightValidateLogVo> list = scPriceconfFreightValidateLogMapper.selectByConditions(pageVo.getStartIndex(),pageVo.getPageSize(),conditions.getBatchId());
        if (list.size() > 0) {
            for (ScPriceconfFreightValidateLogVo sc : list) {
                if (sc.getValidateResultCode().equals(ImportResultCodeEnum.ERROR.getValue())) {
                    sc.setValidateResultCodeString(ImportResultCodeEnum.ERROR.getText());
                } else if (sc.getValidateResultCode().equals(ImportResultCodeEnum.WARN.getValue())) {
                    sc.setValidateResultCodeString(ImportResultCodeEnum.WARN.getText());
                } else if (sc.getValidateResultCode().equals(ImportResultCodeEnum.RIGHT.getValue())) {
                    sc.setValidateResultCodeString(ImportResultCodeEnum.RIGHT.getText());
                }
                if (StringUtils.isEmpty(sc.getImportResult())) {
                    sc.setImportResult("未导入");
                }

            }
        }
        if (null != pageVo) {
//            ScPriceconfFreightValidateLogExample example = new ScPriceconfFreightValidateLogExample();
//            example.setLimitStart(pageVo.getStartIndex());
//            example.setLimitEnd(pageVo.getPageSize());
            pageVo.setTotalRecord(scPriceconfFreightValidateLogMapper.countByExample(example));
        }
        map.put("list", list);
        if (null != pageVo) {
            map.put("page", pageVo);
        }
        return map;
    }

    @Override
    public ScPriceconfFreightValidateLog selectByPrimaryKey(Integer id) throws Exception {
        logger.info("LaborPriceImportServiceImpl.selectByPrimaryKey param : {}", id);
        if (null == id) {
            logger.error("LaborPriceImportServiceImpl.selectByPrimaryKey param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }
        return scPriceconfFreightValidateLogMapper.selectByPrimaryKey(id);
    }

    @Override
    public void update(ScPriceconfFreightVlidateLogForm form, BindingResult br) throws Exception {
        logger.info("LaborPriceImportServiceImpl.update param : {}", form);
        if (form == null) {
            logger.error("LaborPriceImportServiceImpl.update param form must not be null");
            throw new IllegalArgumentException("表单不能为空");
        }
        ScPriceconfFreightValidateLog freight = new ScPriceconfFreightValidateLog();
        BeanUtils.copyProperties(form, freight);
        this.updateSelective(freight);
    }

    public void updateSelective(ScPriceconfFreightValidateLog freight) {
        logger.info("LaborPriceImportServiceImpl.updateSelective param : {}", freight);
        if (null == freight) {
            logger.error("LaborPriceImportServiceImpl.updateSelective param currentFreight must not be null");
            throw new IllegalArgumentException("劳务价格变动不能为空");
        }
        scPriceconfFreightValidateLogMapper.updateByPrimaryKeySelective(freight);
    }

    @Override
    public void del(Integer id) throws Exception {
        logger.info("LaborPriceImportServiceImpl.del param : {}", id);
        if (null == id || 0 == id.intValue()) {
            logger.error("LaborPriceImportServiceImpl.del param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }
        ScPriceconfFreightValidateLog freight = selectByPrimaryKey(id);
        if (null == freight) {
            logger.error("LaborPriceImportServiceImpl.del mile is null");
            throw new BusinessException("记录不存在");
        }
        scPriceconfFreightValidateLogMapper.deleteByPrimaryKey(id);
    }

    @Override
    public void checkData(String batchId) throws Exception {
        //清空日志表需要导入的数据
        ScPriceconfFreightValidateLogExample example = new ScPriceconfFreightValidateLogExample();
        example.createCriteria().andBatchIdEqualTo(batchId);
        List<ScPriceconfFreightValidateLog> list = scPriceconfFreightValidateLogMapper.selectByExample(example);
        if (list.size() == 0) {
            return;
        }
        for (ScPriceconfFreightValidateLog sc : list) {
            sc.setValidateResultCode(null);
            sc.setValidateResult(null);
        }
        scPriceconfFreightValidateLogMapper.validateResultBatchUpdate(list);
        //校验线路是否重复
        List<ScPriceconfFreightValidateLog> list1 = scPriceconfFreightValidateLogMapper.selectRouteNameRepeat(batchId);
        if (list1.size() > 0) {
            for (ScPriceconfFreightValidateLog sc : list1) {
                writeResult(sc, LaborImportResultEnum.ROUTE_REPEAT.getText(), ImportResultCodeEnum.ERROR.getValue());
            }
            scPriceconfFreightValidateLogMapper.validateResultBatchUpdate(list1);
        }

        ScPriceconfFreightValidateLogExample example1 = new ScPriceconfFreightValidateLogExample();
        example1.createCriteria().andBatchIdEqualTo(batchId);
        List<ScPriceconfFreightValidateLog> list2 = scPriceconfFreightValidateLogMapper.selectByExample(example1);
        if (list2.size() > 0) {
            for (ScPriceconfFreightValidateLog sc : list2) {
                //校验线路是否为空
                if (StringUtils.isEmpty(sc.getRouteName())) {
                    writeResult(sc, LaborImportResultEnum.ROUTE_NAME_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                }
                //校验起始省是否为空
                if (StringUtils.isEmpty(sc.getOriginProvinceName())) {
                    writeResult(sc, LaborImportResultEnum.ORIGIN_PROVINCE_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                }
                //校验起始地是否为空
                if (StringUtils.isEmpty(sc.getOriginAreaName())) {
                    writeResult(sc, LaborImportResultEnum.ORIGIN_AREA_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                }
                //校验目的省是否为空
                if (StringUtils.isEmpty(sc.getDestProvinceName())) {
                    writeResult(sc, LaborImportResultEnum.DEST_PROVINCE_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                }
                //校验目的地是否为空
                if (StringUtils.isEmpty(sc.getDestAreaName())) {
                    writeResult(sc, LaborImportResultEnum.DEST_AREA_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                }
                //校验公里数是否为空
                if (sc.getMiles() == null) {
                    writeResult(sc, LaborImportResultEnum.MILES_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                } else {
                    //校验公里数是否大于零
                    if (sc.getMiles().compareTo(BigDecimal.ZERO) == -1) {
                        writeResult(sc, LaborImportResultEnum.MILES_THAN_ZERO.getText(), ImportResultCodeEnum.ERROR.getValue());
                    }
                }
                //校验劳务价是否为空
                if (sc.getCurrentValue() == null) {
                    writeResult(sc, LaborImportResultEnum.CURRENT_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                } else {
                    //校验劳务价是否大于零
                    if (sc.getCurrentValue().compareTo(BigDecimal.ZERO) == -1) {
                        writeResult(sc, LaborImportResultEnum.CURRENT_THAN_ZERO.getText(), ImportResultCodeEnum.ERROR.getValue());
                    }
                }
                //校验生效日期是否为空
                if (sc.getEffectiveDate() == null) {
                    writeResult(sc, LaborImportResultEnum.EFFECTIVE_DATE_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                } else {
                    //校验生效日期是否大于当前日期
                    if ((sc.getEffectiveDate().getTime()) < (new Date().getTime())) {
                        writeResult(sc, LaborImportResultEnum.EFFECTIVE_DATE_THAN_NOW.getText(), ImportResultCodeEnum.ERROR.getValue());
                    }
                    //校验生效日期是否大于已存在生效日期
                    ScPriceconfFreight scPriceconfFreight = scPriceconfFreightMapper.queryMaxEffectiveDate(sc.getRouteName());
                    if (scPriceconfFreight != null && scPriceconfFreight.getEffectiveDate().getTime() >= sc.getEffectiveDate().getTime()) {
                        writeResult(sc, LaborImportResultEnum.EFFECTIVE_DATE_THAN_BEFORE.getText(), ImportResultCodeEnum.ERROR.getValue());
                    } else {
                        ScPriceconfMile scPriceconfMile = scPriceconfMileMapper.queryMaxEffectiveDate(sc.getRouteName());
                        if (scPriceconfMile != null && scPriceconfMile.getEffectiveDate().getTime() >= sc.getEffectiveDate().getTime()) {
                            writeResult(sc, LaborImportResultEnum.EFFECTIVE_DATE_THAN_BEFORE.getText(), ImportResultCodeEnum.ERROR.getValue());
                        }
                    }
                }

            }
            scPriceconfFreightValidateLogMapper.validateResultBatchUpdate(list2);
        }
        //校验线路是否存在
        ScPriceconfFreightValidateLogExample example2 = new ScPriceconfFreightValidateLogExample();
        example2.createCriteria().andOriginProvinceNameIsNotNull().andOriginAreaNameIsNotNull().andDestAreaNameIsNotNull();
        List<ScPriceconfFreightValidateLog> list3 = scPriceconfFreightValidateLogMapper.selectByExample(example2);
        DRouteExample example3 = new DRouteExample();
        List<DRoute> list4 = dRouteMapper.selectByExample(example3);
        if (list3.size() > 0 && list4.size() > 0) {
            List<ScPriceconfFreightValidateLog> list6 = new ArrayList<ScPriceconfFreightValidateLog>();
            for (ScPriceconfFreightValidateLog sc : list3) {
                list6.add(sc);
            }
            for (DRoute dr : list4) {
                for (ScPriceconfFreightValidateLog sc : list3) {
                    if (sc.getOriginProvinceName().equals(dr.getoProvince()) && sc.getOriginAreaName().equals(dr.getoTag())
                            && sc.getDestProvinceName().equals(dr.getdProvince()) && sc.getDestAreaName().equals(dr.getdTag())) {
                        list6.remove(sc);
                    }
                }
            }
            if (list6.size() > 0) {
                for (ScPriceconfFreightValidateLog sc : list6) {
                    writeResult(sc, LaborImportResultEnum.LINE_NOT_EXIST.getText(), ImportResultCodeEnum.WARN.getValue());
                }
                scPriceconfFreightValidateLogMapper.validateResultBatchUpdate(list6);
            }
        }
        //校验正确
        ScPriceconfFreightValidateLogExample example4 = new ScPriceconfFreightValidateLogExample();
        example4.createCriteria().andValidateResultIsNull();
        List<ScPriceconfFreightValidateLog> list5 = scPriceconfFreightValidateLogMapper.selectByExample(example4);
        if (list5.size() > 0) {
            for (ScPriceconfFreightValidateLog sc : list5) {
                sc.setValidateResultCode(ImportResultCodeEnum.RIGHT.getValue());
            }
            scPriceconfFreightValidateLogMapper.validateResultBatchUpdate(list5);
        }

    }

    @Override
    public void importFreightAndMile(String batchId) throws Exception {
        //获取所有要插入的数据
        ScPriceconfFreightValidateLogExample example = new ScPriceconfFreightValidateLogExample();
        example.createCriteria().andValidateResultCodeBetween(ImportResultCodeEnum.WARN.getValue(), ImportResultCodeEnum.RIGHT.getValue()).andBatchIdEqualTo(batchId);
        List<ScPriceconfFreightValidateLog> listAll = scPriceconfFreightValidateLogMapper.selectByExample(example);
        if(listAll.size() == 0){
            throw new BusinessException("导入数据为空");
        }
        //去掉已经导入成功的数据
        List<ScPriceconfFreightValidateLog> listData = new ArrayList<ScPriceconfFreightValidateLog>();
        for (ScPriceconfFreightValidateLog sc : listAll) {
            listData.add(sc);
        }
        for (ScPriceconfFreightValidateLog sc : listAll) {
            ScPriceconfFreightImportLogExample exampleLog = new ScPriceconfFreightImportLogExample();
            exampleLog.createCriteria().andDataIdEqualTo(sc.getId()).andImportResultCodeEqualTo(ImportResultCodeEnum.SUCCESS.getValue());
            List<ScPriceconfFreightImportLog> listLog = scPriceconfFreightImportLogmapper.selectByExample(exampleLog);
            if (listLog.size() > 0){
                listData.remove(sc);
            }
        }

        if (listData.size() > 0) {
            //获取线路信息
            DRouteExample example1 = new DRouteExample();
            List<DRoute> listRoute = dRouteMapper.selectByExample(example1);
            //获取需要添加线路的数据
            ScPriceconfFreightValidateLogExample example2 = new ScPriceconfFreightValidateLogExample();
            example2.createCriteria().andValidateResultCodeEqualTo(ImportResultCodeEnum.WARN.getValue());
            List<ScPriceconfFreightValidateLog> listAdd = scPriceconfFreightValidateLogMapper.selectByExample(example2);
            if (listAdd.size() > 0) {
                List<DRoute> list = new ArrayList<DRoute>();
                for (ScPriceconfFreightValidateLog sc : listData) {
                    DRoute route = new DRoute();
                    route.setName(sc.getRouteName());
                    route.setoProvince(sc.getOriginProvinceName());
                    route.setoTag(sc.getOriginAreaName());
                    route.setdProvince(sc.getDestProvinceName());
                    route.setdTag(sc.getDestAreaName());
                    list.add(route);
                }
                //插入新增线路
                dRouteMapper.insertList(list);
            }
            //插入正式表
            if (listRoute.size() > 0) {
                for (DRoute dr : listRoute) {
                    for (ScPriceconfFreightValidateLog sc : listData) {
                        if (sc.getOriginProvinceName().equals(dr.getoProvince()) && sc.getOriginAreaName().equals(dr.getoTag())
                                && sc.getDestProvinceName().equals(dr.getdProvince()) && sc.getDestAreaName().equals(dr.getdTag())) {
                            ScPriceconfFreight freight = new ScPriceconfFreight();
                            ScPriceconfMile mile = new ScPriceconfMile();
                            freight.setRouteId(dr.getId());
                            freight.setCurrentValue(sc.getCurrentValue());
                            freight.setEffectiveDate(sc.getEffectiveDate());
                            freight.setGmtCreate(new Date());
                            freight.setGmtUpdate(new Date());
                            mile.setRouteId(dr.getId());
                            mile.setCurrentValue(sc.getMiles());
                            mile.setEffectiveDate(sc.getEffectiveDate());
                            mile.setGmtCreate(new Date());
                            mile.setGmtUpdate(new Date());
                            ScPriceconfFreightImportLog scPriceconfFreightImportLog = new ScPriceconfFreightImportLog();
                            try {
                                scPriceconfFreightMapper.insert(freight);
                                scPriceconfMileMapper.insert(mile);
                                writeScPriceconfFreightImportLog(scPriceconfFreightImportLog, ImportResultCodeEnum.SUCCESS.getValue(), ImportResultCodeEnum.SUCCESS.getText(), sc.getId());
                                scPriceconfFreightImportLogmapper.insert(scPriceconfFreightImportLog);
                            } catch (Exception e) {
                                writeScPriceconfFreightImportLog(scPriceconfFreightImportLog, ImportResultCodeEnum.FAIL.getValue(), ImportResultCodeEnum.FAIL.getText(), sc.getId());
                                scPriceconfFreightImportLogmapper.insert(scPriceconfFreightImportLog);
                                throw new Exception("插入异常");
                            }
                        }
                    }
                }
            }
        }
    }
    @Override
    public void deleteAll() throws Exception {
        //清空表数据
        ScPriceconfFreightValidateLogExample example3 = new ScPriceconfFreightValidateLogExample();
//        List<ScPriceconfFreightValidateLogVo> forms = scPriceconfFreightValidateLogMapper.selectByConditions(example3);
//        int i = 0;
//        if (forms.size() > 0) {
//            for (ScPriceconfFreightValidateLogVo vo : forms) {
//                if (vo.getImportResultCode() != null && vo.getImportResultCode().equals(ImportResultCodeEnum.SUCCESS.getValue())) {
//                    i = i + 1;
//                }
//            }
//            if (forms.size() == i) {
//                scPriceconfFreightValidateLogMapper.deleteAll();
//                scPriceconfFreightImportLogmapper.deleteAll();
//            }
//        }
    }

    @Override
    public void delete() throws Exception {
        try {
            scPriceconfFreightValidateLogMapper.deleteAll();
            scPriceconfFreightImportLogmapper.deleteAll();
        }catch (Exception e){
            throw new BusinessException(e.getMessage());
        }

    }


    @Override
    public void checkInvalidDate() throws Exception {
        //校验ScPriceconfFreight失效日期
        List<ScPriceconfFreight> list1 = scPriceconfFreightMapper.selectRouteIdRepeat();
        if (list1.size() > 0) {
            for (ScPriceconfFreight sc1 : list1) {
                if (sc1.getInvalidDate() == null) {
                    for (ScPriceconfFreight sc2 : list1) {
                        if (sc1.getRouteId().equals(sc2.getRouteId()) && sc1.getId() != sc2.getId()
                                && sc1.getEffectiveDate().getTime() < sc2.getEffectiveDate().getTime()) {
                            ScPriceconfFreight scPriceconfFreight = new ScPriceconfFreight();
                            scPriceconfFreight.setId(sc1.getId());
                            scPriceconfFreight.setInvalidDate(sc2.getEffectiveDate());
                            scPriceconfFreight.setGmtUpdate(new Date());
                            scPriceconfFreightMapper.updateByPrimaryKeySelective(scPriceconfFreight);
                        }
                    }
                }
            }
        }
        //校验ScPriceconfMile失效日期
        List<ScPriceconfMile> list3 = scPriceconfMileMapper.selectRouteIdRepeat();
        if (list3.size() > 0) {
            for (ScPriceconfMile sc1 : list3) {
                if (sc1.getInvalidDate() == null) {
                    for (ScPriceconfMile sc2 : list3) {
                        if (sc1.getRouteId().equals(sc2.getRouteId()) && sc1.getId() != sc2.getId()
                                && sc1.getEffectiveDate().getTime() < sc2.getEffectiveDate().getTime()) {
                            ScPriceconfMile scPriceconfMile = new ScPriceconfMile();
                            scPriceconfMile.setId(sc1.getId());
                            scPriceconfMile.setInvalidDate(sc2.getEffectiveDate());
                            scPriceconfMile.setGmtUpdate(new Date());
                            scPriceconfMileMapper.updateByPrimaryKeySelective(scPriceconfMile);
                        }
                    }
                }
            }
        }
    }

    private ScPriceconfFreightValidateLog writeResult(ScPriceconfFreightValidateLog sc, String result, Integer resultCode) {
        if (StringUtils.isEmpty(sc.getValidateResult())) {
            sc.setValidateResult(result);
        } else {
            sc.setValidateResult(sc.getValidateResult() + "," + result);
        }
        if (sc.getValidateResultCode() != null && resultCode == ImportResultCodeEnum.WARN.getValue()
                && sc.getValidateResultCode() == ImportResultCodeEnum.ERROR.getValue()) {

        } else {
            sc.setValidateResultCode(resultCode);
        }
        return sc;
    }

    private ScPriceconfFreightImportLog writeScPriceconfFreightImportLog(ScPriceconfFreightImportLog sc, Integer resultCode, String result, Integer id) {
        sc.setImportResultCode(resultCode);
        sc.setImportResult(result);
        sc.setGmtCreate(new Date());
        sc.setGmtUpdate(new Date());
        sc.setDataId(id);
        return sc;
    }

}
